package com.engine.jucailinkq.attendance.workflow.service.impl;

import com.engine.jucailinkq.attendance.workflow.service.EnterpriseCalendarService;
import com.engine.core.impl.Service;
import com.engine.jucailinkq.common.util.*;
import weaver.general.BaseBean;
import weaver.general.Util;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: sy
 * @Description: 企业日历实现类
 * @Date: 2024/4/19
 **/
public class EnterpriseCalendarServiceImpl extends Service implements EnterpriseCalendarService {
    BaseBean bs = new BaseBean();
    @Override
    public Map<String, Object> initCalendar(Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        String yearStr = Util.null2String(params.get("year"));
        String calendarId = Util.null2String(params.get("calendarId"));
        if ("".equals(yearStr) || "".equals(calendarId)) {
            result.put("status", "false");
            result.put("message", "年份和日历必填！");
            return result;
        }
        int year = Integer.parseInt(yearStr);
        //查询所属机构
        String sql = "select * from uf_jcl_kq_rlmc where id = " + calendarId;
        Map<String,Object> data = DbTools.getSqlToMap(sql);
        if (data.size() > 0) {
            //所属机构
            String org = Util.null2String(data.get("szjg"));
            //单双休设置相关信息
            //单双休设置，标准双休-0，单双休-1，单休-2
            String restDaySetting = Util.null2String(data.get("dxzsz"));
            //双周休息日，周一-周日，0-6
            String doubleRestDays = Util.null2String(data.get("dzxxr"));
            //单周休息日，周一-周日，0-6
            String singleRestDays = Util.null2String(data.get("xzxxr"));
            //单双休轮转设置，先单后双-0，先双后单-1
            String restDayTransSetting = Util.null2String(data.get("dxzz"));
            //是否按上一年继续轮转
            String transContinue= Util.null2String(data.get("asynjx"));
            //在单双周轮换时，判断第一周的休息日情况
            boolean doubleRestSign = true;
            if (restDaySetting.equals("1")) {
                doubleRestSign = restDayTransSetting.equals("1");
                if (transContinue.equals("1")) {
                    doubleRestSign = checkFirstWeekRest(year, calendarId, doubleRestSign);
                }
            }

            //查询formmodeid
            Map<String,String> formModeIdMap = Utils.getFormmodeIdMap();
            String formModeId = formModeIdMap.get("uf_jcl_kq_rlxx");
            Calendar calendar = Calendar.getInstance();
            List<Map<String, Object>> dateInfoList = new ArrayList<>();
            Map<String, Object> dateInfo;
            for (int i = 1; i <= 12; i++) {
                calendar.set(year, i - 1, 1);
                int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

                for (int day = 0; day < daysInMonth; day++) {
                    dateInfo = new HashMap<>();
                    dateInfo = createDateInfo(calendar);
                    dateInfo.put("formmodeid",formModeId);
                    dateInfo.put("modeuuid", UUID.randomUUID().toString());
                    dateInfo.put("modedatacreater","1");
                    dateInfo.put("modedatacreatertype","0");
                    dateInfo.put("modedatacreatedate", DateUtil.getCurrentTime().split(" ")[0]);
                    dateInfo.put("modedatacreatetime",DateUtil.getCurrentTime().split(" ")[1]);
                    dateInfo.put("rlmc", calendarId);
                    dateInfo.put("nd", yearStr);
                    dateInfo.put("szjg", org);
                    //判断日历设置是否有单双休相关数值，并修改日期类型
                    //双休时，判断双休休息日是否包括当前日期的星期值，休息日类型低于节假日类型
                    if ("0".equals(restDaySetting) && doubleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                        dateInfo.put("rqlx", "2");
                    }
                    //单休时，判断单休休息日是否包括当前日期的星期值，休息日类型低于节假日类型
                    else if ("2".equals(restDaySetting) && singleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                        dateInfo.put("rqlx", "2");
                    }
                    //单双休时，判断当前周是单休还是双休，并在各自得情况下判断休息日是否包括当前日期的星期值，休息日类型低于节假日类型
                    else if ("1".equals(restDaySetting)) {
                        if (doubleRestSign && doubleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                            dateInfo.put("rqlx", "2");
                        } else if (!doubleRestSign && singleRestDays.contains(dateInfo.get("xq").toString()) && !"1".equals(dateInfo.get("rqlx"))) {
                            dateInfo.put("rqlx", "2");
                        }
                        //单双休时，每一周都要轮换单双休状态
                        if ("6".equals(dateInfo.get("xq"))) {
                            doubleRestSign = !doubleRestSign;
                        }
                    }
                    dateInfoList.add(dateInfo);
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                }
            }
            //删除老数据
            String delSql = "delete from uf_jcl_kq_rlxx where rlmc = " + calendarId + " and nd = " + yearStr;
            boolean delSign = DbTools.update(delSql);
            bs.writeLog("delSign : " +  delSign + ", delSql : " + delSql);
            //插入新数据
            String tableName = "uf_jcl_kq_rlxx";
            if (dateInfoList.size() > 0) {
                bs.writeLog("入库开始---");
                boolean insertSign = CommonUtil.insertBatch(dateInfoList, tableName);
                bs.writeLog("insertSign : " + insertSign);
                result.put("status", String.valueOf(insertSign));
                result.put("message", insertSign ? "初始化成功" : "初始化失败， 插入新数据未成功");
            } else {
                result.put("status", "false");
                result.put("message", "初始化失败, 未生成新数据");
            }

        } else {
            result.put("status", "false");
            result.put("message", "初始化失败, 日历信息不存在");
        }
        return result;
    }

    private boolean checkFirstWeekRest(int year, String calendarId, boolean doubleRestSign) {
        Calendar calendar =Calendar.getInstance();
        calendar.set(year, Calendar.JANUARY, 1);
        String firstDayWeek = getWeek(calendar);
        int lastYear = year -1;
        int firstIndex = Integer.parseInt(firstDayWeek);
        //获取目标年度第一天所在周的之前的一周日期
        List<String> lastWeekDays = new ArrayList<>();
        for (int i = 1; i <= 7; i++) {
            lastWeekDays.add(lastYear + "-12-" + (31 - firstIndex));
            firstIndex++;
        }
        //查询上一步中查询的日期中有几个公休日
        String sql = "select * from uf_jcl_kq_rlxx where rlmc = " + calendarId + " and nd =" + lastYear+ " and rq in ('"+String.join("','",lastWeekDays)+"')";
        List<Map<String,Object>> data = DbTools.getSqlToList(sql);
        int restDayNum = 0;
        if (data.size() > 0) {
            for (Map<String,Object> map : data) {
                if (Util.null2String(map.get("rqlx")).equals("2")) {
                    restDayNum++;
                }
            }
            return restDayNum < 2;
        } else {
            return doubleRestSign;
        }
    }

    private Map<String, Object> createDateInfo(Calendar calendar) {
        Map<String, Object> dateInfo = new HashMap<>();
        // 获取阳历年-月-日
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 使用SimpleDateFormat格式化Calendar中的日期
        String solarDate  = sdf.format(calendar.getTime());
        //获取农历日期
        LunarCalendar lunarCalendar = new LunarCalendar(calendar);
        String lunarDate = lunarCalendar.traditionLunarDay();
        //获取目标日期是周几, 此功能中周一-周日为0-6
        String weekIndex = getWeek(calendar);
        //获取日期特定名称，节气或节日
        String specialDay = "";
        //判断日期是否为节气
        SolarTermsUtil solarTermsUtil = new SolarTermsUtil(calendar);
        String termInfo = solarTermsUtil.getSolartermsMsg();
        if (!termInfo.equals("")) {
            specialDay = termInfo.replace(" ", "");
        }
        //判断日期是否为节日
        String holidayInfo = getHolidayInfo(calendar, lunarCalendar);
        if (!holidayInfo.equals("")) {
            specialDay = specialDay + holidayInfo;
        }
        //判断日期类型
        String dayType = getDayType(weekIndex, specialDay);
        dateInfo.put("rq", solarDate);
        dateInfo.put("nlrq", lunarDate);
        dateInfo.put("xq", weekIndex);
        dateInfo.put("mc", specialDay.equals("") ? null : specialDay);
        dateInfo.put("rqlx", dayType);
        return dateInfo;
    }

    private String getDayType(String weekIndex, String specialDay) {
        String dayType = "0";
        List<String> realHolidayList = new ArrayList<>();
        realHolidayList.add("春节");
        realHolidayList.add("元旦节");
        realHolidayList.add("劳动节");
        realHolidayList.add("国庆节");
        realHolidayList.add("端午节");
        realHolidayList.add("中秋节");
        realHolidayList.add("清明");
        for (String holiday : realHolidayList) {
            if (specialDay.contains(holiday)) {
                dayType = "1";
                break;
            }
        }
//        if (!"1".equals(dayType)) {
//            if ("5".equals(weekIndex) || "6".equals(weekIndex)) {
//                dayType = "2";
//            }
//        }
        return dayType;
    }

    private String getHolidayInfo(Calendar calendar, LunarCalendar lunarCalendar) {
        String holidayInfo = "";
        //公历节日
        int solarMonth = calendar.get(Calendar.MONTH) + 1; // Calendar.MONTH 从0开始计数
        int solarDay = calendar.get(Calendar.DAY_OF_MONTH);
        if (solarMonth == 1 && solarDay == 1) {
            holidayInfo = holidayInfo + "元旦节";
        }
        if (solarMonth == 2 && solarDay == 14) {
            holidayInfo = holidayInfo + "情人节";
        }
        if (solarMonth == 3 && solarDay == 8) {
            holidayInfo = holidayInfo + "妇女节";
        }
        if (solarMonth == 3 && solarDay == 12) {
            holidayInfo = holidayInfo + "植树节";
        }
        if (solarMonth == 4 && solarDay == 1) {
            holidayInfo = holidayInfo + "愚人节";
        }
        if (solarMonth == 5 && solarDay == 1) {
            holidayInfo = holidayInfo + "劳动节";
        }
        if (solarMonth == 5 && solarDay == 4) {
            holidayInfo = holidayInfo + "中国青年节";
        }
        if (solarMonth == 6 && solarDay == 1) {
            holidayInfo = holidayInfo + "儿童节";
        }
        if (solarMonth == 7 && solarDay == 1) {
            holidayInfo = holidayInfo + "建党节";
        }
        if (solarMonth == 8 && solarDay == 1) {
            holidayInfo = holidayInfo + "建军节";
        }
        if (solarMonth == 9 && solarDay == 10) {
            holidayInfo = holidayInfo + "教师节";
        }
        if (solarMonth == 10 && solarDay == 1) {
            holidayInfo = holidayInfo + "国庆节";
        }
        //农历节日，春节
        int lunarMonth = lunarCalendar.getMonth();
        int lunarDay = lunarCalendar.getDay();

        if (lunarMonth == 1 && lunarDay == 1) {
            holidayInfo = holidayInfo + "春节";
        }
        if (lunarMonth == 1 && lunarDay == 15) {
            holidayInfo = holidayInfo + "元宵节";
        }
        if (lunarMonth == 5 && lunarDay == 5) {
            holidayInfo = holidayInfo + "端午节";
        }
        if (lunarMonth == 7 && lunarDay == 7) {
            holidayInfo = holidayInfo + "七夕节";
        }
        if (lunarMonth == 8 && lunarDay == 15) {
            holidayInfo = holidayInfo + "中秋节";
        }
        if (lunarMonth == 9 && lunarDay == 9) {
            holidayInfo = holidayInfo + "重阳节";
        }
        //除夕特殊处理
        if (lunarMonth == 12) {
            int monthDays = LunarCalendar.monthDays(lunarCalendar.getYear(), lunarMonth);
            if (monthDays == lunarDay) {
                holidayInfo = holidayInfo + "除夕";
            }
        }
        return holidayInfo;
    }

    //根据日期取得星期几，
    public static String getWeek(Calendar cal){
        //日历详细表中字段xq枚举值与该方法中的周几值存在差值，故存在相关处理逻辑
        int weekIndex = cal.get(Calendar.DAY_OF_WEEK) - 2;
        if(weekIndex<0){
            weekIndex = 6;
        }
        return String.valueOf(weekIndex);
    }
}
